package com.example.speedwaymanager;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.Log;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

public final class CUtils {
	private static final String kFileNameEliga = "eliga.xml";
	private static final String kFileNameTeams = "teams.xml";
	private static final String kFileNameDmp = "dmp.xml";
	private static CGameManager gm = CGameManager.getInstance();
	
	// XML node keys
	static final String KEY_RIDER = "RIDER"; // parent node
	static final String KEY_RANK = "RANK";
	static final String KEY_NAME = "NAME";
	static final String KEY_TEAM = "TEAM";
	static final String KEY_AVG = "AVG";
	static final String KEY_AVGHOME = "AVGHOME";
	static final String KEY_AVGAWAY = "AVGAWAY";
	static final String KEY_TEAMS = "TEAMS";
	static final String KEY_PROGRAM = "PROGRAM";
	static final String KEY_HEAT = "HEAT";
	static final String KEY_GATE = "GATE";
	static final String KEY_NO = "NO";
	static final String KEY_COLOR = "COLOR";
	static final String KEY_TYPE = "TYPE";

	static public void loadDatabaseFromXml(AssetManager assetManager, ArrayList<CRider> ridersList) {
		String xml = getStringFromAsset(assetManager, kFileNameEliga);
		Document xmlDoc = XMLfromString(xml);
		NodeList nodes = xmlDoc.getElementsByTagName(KEY_RIDER);
		for (int i = 0; i < nodes.getLength(); i++) {
			Element e = (Element) nodes.item(i);
			if (Node.ELEMENT_NODE == e.getNodeType()) {
				ridersList.add(new CRider(getTagValue(KEY_RANK, e),
						getTagValue(KEY_NAME, e), getTagValue(KEY_TEAM, e),
						getTagValue(KEY_AVG, e), getTagValue(KEY_AVGHOME, e),
						getTagValue(KEY_AVGAWAY, e), getTagValue(KEY_TYPE, e)));
			}
		}
	}

	public static void loadScheduleFromXml(AssetManager assetManager, CSchedule schedule) {
		String xml = getStringFromAsset(assetManager, kFileNameDmp);
        Document xmlDoc;
        xmlDoc = XMLfromString(xml);
        NodeList nodes = xmlDoc.getElementsByTagName(KEY_GATE);
        ArrayList<CGate> gates = new ArrayList<CGate>();
        ArrayList<CHeat> heats = new ArrayList<CHeat>();
        int counter = 0;
        for (int i = 0; i < nodes.getLength(); i++) {
			Element e = (Element) nodes.item(i);
			if (Node.ELEMENT_NODE == e.getNodeType()) {
				gates.add(new CGate(getTagValue(KEY_NO, e), getTagValue(KEY_COLOR, e)));
				counter++;
			}
			if (counter >= 4) {
				heats.add(new CHeat(gates));
				gates.clear();
				counter = 0;
			}
		}
		schedule.set_heat(heats);
	}

	static public void loadTeamsFromXml(AssetManager assetManager, ArrayList<String> teamsList) {
        /*
        teamsList.add("Unia Tarnów");
        teamsList.add("Stal Gorzów");
        teamsList.add("Unibax Toruń");
        teamsList.add("Stelmet Falubaz Zielona Góra");
        teamsList.add("Fogo Unia Leszno");
        teamsList.add("PGE Marma Rzeszów");
        teamsList.add("składywęglapl Polonia Bydgoszcz");
        teamsList.add("Dospel Włókniarz Częstochowa");
        teamsList.add("Betard Sparta Wrocław");
        teamsList.add("Lechma Start Gniezno");
        */
        String xml = getStringFromAsset(assetManager, kFileNameTeams);
        Document xmlDoc = XMLfromString(xml);
        NodeList nodes = xmlDoc.getElementsByTagName(KEY_TEAMS);
        for (int i = 0; i < nodes.getLength(); i++) {
            Element e = (Element) nodes.item(i);
            if (e.ELEMENT_NODE == e.getNodeType()) {
                teamsList.add(getTagValue(KEY_TEAM, e));
            }
        }
	}

	/**
	 * change gates (numbers only) 
	 * @param match
	 * @param heat
     * @param newRider
     * @param oldRider
     */
    public static void changeGatesInHeat(CMatch match, int heat, CRider newRider, CRider oldRider) {
        ArrayList<CGate> gates = match.get_schedule().get_heat().get(heat).get_gates();
		for (int i = 0; i < gates.size(); ++i )
		{
			if ( oldRider.get_number() == gates.get(i)._no )
			{
				gates.get(i)._no = newRider.get_number(); 
			}
		}
	}
	
	public static CTeam getTeamByName(String name)
	{
		ArrayList<CTeam> teams = gm.get_teamsList();
		for (CTeam team : teams) {
			if ( team.get_name().equals(name) )
				return team;
		}
		return null;
	}
	
	ArrayList<CTeam> teams = gm.get_teamsList();
	private static String getTagValue(String sTag, Element eElement) {
		NodeList nlList = eElement.getElementsByTagName(sTag).item(0)
				.getChildNodes();
		Node nValue = nlList.item(0);
		return nValue.getNodeValue();
	}

	public static Document XMLfromString(String xml) {
		Document doc = null;

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			doc = db.parse(is);

		} catch (ParserConfigurationException e) {
			System.out.println("XML parse error: " + e.getMessage());
			return null;
		} catch (SAXException e) {
			System.out.println("Wrong XML file structure: " + e.getMessage());
			return null;
		} catch (IOException e) {
			System.out.println("I/O exeption: " + e.getMessage());
			return null;
		}

		return doc;
	}

	/**
	 * Gets data from assets
	 * 
	 * @param filename
	 * @return String from asset
	 */
	public static String getStringFromAsset(AssetManager assetManager, String filename) {		
		InputStream inputStream = null;
		try {
			inputStream = assetManager.open(filename);
		} catch (IOException e) {
			Log.e("tag", e.getMessage());
		}
		String s = readTextFile(inputStream);
		// Log.d("LNO", s);
		return s;

	}

	/**
	 * Read text form file.
	 * 
	 * Helper for loading data
	 * 
	 * @param inputStream
	 * @return
	 */
	public static String readTextFile(InputStream inputStream) {
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

		byte buf[] = new byte[1024];
		int len;
		try {
			while ((len = inputStream.read(buf)) != -1) {
				outputStream.write(buf, 0, len);
			}
			outputStream.close();
			inputStream.close();
		} catch (IOException e) {

		}
		return outputStream.toString();
	}

	public static void saveTextToFile(MainActivity main, String filename,
			ArrayList<String> match) {
		FileOutputStream outputStream;
		try {
			outputStream = main.openFileOutput(filename, Context.MODE_PRIVATE);
			for (String str : match) {
				outputStream.write(str.getBytes());
			}
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
